package com.ruoyi.program.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.program.domain.DTO.LoginWechatDto;
import com.ruoyi.program.domain.DTO.UserWechat;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.Map;
import java.util.Set;

@RestController
@RequestMapping("/program")
public class LoginController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private ISysRoleService roleService;

    @Value("${wechat.miniapp.appid}")
    private String appid;

    @Value("${wechat.miniapp.secret}")
    private String secret;

    // 微信code2session接口地址
    private static final String WECHAT_CODE2SESSION_URL =
            "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code";


    /**
     * 微信小程序登录接口
     * 接收code -> 换取openid -> 映射若依用户 -> 生成Token
     */
    @Anonymous
    @PostMapping("/login")
    public AjaxResult wechatLogin(@RequestBody LoginWechatDto loginDto) {

        try{
            // 1. 获取前端传递的code（已通过@Valid校验非空）
            String code = loginDto.getCode();

            System.out.println("----------code-------"+code);

            // 2. 调用微信官方接口，换取openid和session_key
            String requestUrl = String.format(WECHAT_CODE2SESSION_URL, appid, secret, code);
            System.out.println("----------requestUrl-------"+requestUrl);

            // 调用微信接口并接收返回结果（返回格式为JSON，用Map接收）
            String response = restTemplate.getForObject(requestUrl, String.class);
            System.out.println("微信返回：" + response);

            ObjectMapper mapper = new ObjectMapper();
            Map<String, Object> wechatResp = mapper.readValue(response, Map.class);


            // 3. 处理微信接口返回结果（错误判断）
            if (wechatResp == null) {
                return AjaxResult.error("调用微信登录接口失败，未获取到返回数据");
            }
            // 微信接口返回错误码（errcode不为0则失败）
            if (wechatResp.containsKey("errcode") && !"0".equals(wechatResp.get("errcode").toString())) {
                String errMsg = wechatResp.get("errmsg") != null ? wechatResp.get("errmsg").toString() : "未知错误";
                return AjaxResult.error("微信登录失败：" + errMsg);
            }

            // 4. 提取微信返回的核心信息
            String openid = wechatResp.get("openid").toString(); // 用户在当前小程序的唯一标识
            String sessionKey = wechatResp.get("session_key").toString(); // 解密敏感信息的密钥（按需存储）
            System.out.println("----------sessionKey-------"+sessionKey);
            System.out.println("----------openid-------"+openid);

            // 5. 映射若依系统用户（通过openid关联）
            // 5.1 查询是否已存在该openid对应的用户
            SysUser user = userService.selectUserByOpenId(openid);

            System.out.println("--user---"+user);

            // 5.2 若用户不存在，自动创建新用户（首次登录）
            if (user == null) {
                user = new SysUser();
                user.setOpenId(openid); // 存储openid，建立映射关系
                user.setUserName("wx_" + openid.substring(0, 8)); // 生成唯一用户名（避免重复）
                user.setNickName("小程序用户"); // 默认昵称
                user.setPassword(SecurityUtils.encryptPassword("123456"));
                user.setStatus("0"); // 账号状态：正常（0=正常，1=禁用）

                System.out.println("------user-------"+user);
                // 调用若依用户服务创建用户
                userService.insertUser(user);
            }

            SysUser fullUser = null;

            if(user == null){
                System.out.println("------查openid-------");
                fullUser = userService.selectUserByOpenId(openid); // 查完整用户信息
            }else {
                System.out.println("------查用户id-------");
                fullUser = userService.selectUserById(user.getUserId()); // 查完整用户信息
            }
            // 6. 修正：手动构建LoginUser（用若依默认服务）
            if (fullUser == null) {
                return AjaxResult.error("用户信息查询失败");
            }
            Set<String> roleSet = roleService.selectRolePermissionByUserId(user.getUserId());

            LoginUser loginUser = new LoginUser(
                    fullUser.getUserId(),
                    fullUser.getDeptId(),
                    fullUser,
                    roleSet
            );

            // 7. 生成Token
            String token = tokenService.createToken(loginUser);

            UserWechat userWechat = new UserWechat(
                    token,
                    user.getAvatar(),
                    user.getUserName(),
                    user.getNickName(),
                    user.getEmail(),
                    user.getPhonenumber()
            );

            // 8. 返回结果
            return AjaxResult.success()
                    .put("userinfo", userWechat)
                    .put("msg", "登录成功");

        }catch (Exception e) {
            // 捕获所有异常，返回友好提示
            return AjaxResult.error("登录异常：" + e.getMessage());
        }
    }
}
